#include <avr/io.h>
#include <avr/interrupt.h>

#include "SOLARMAIN.h"

uint16_t timerCounter16bit = 0;
uint8_t timerCounter8bit = 0;
uint16_t preFlightBatteryVoltageCounter = 0;
uint8_t state = preflight;					//Set start state to pre-flight
uint8_t LOcounter = 0;



/*
	Initializes the 8bit and 16bit timers, and sets their corresponding breaktimes aswell as enabling their interrupts
*/
void inittimer()
{
	//8-bit timer setup
	TCCR2A |= 1<<WGM21;									//Timer will restart when reaching specific value (OCR2A)
	TCCR2B |= 1<<CS22 | 1<<CS21 | 1<<CS20;				//Prescaler set to 1024 (8MHz -> 7812.5 ticks/s)
	TIMSK2 |= 1<<OCIE2A;								//Enable interrupt
	OCR2A = 255;										//Timer lookup value
	
	//16-bit timer setup
	TCCR1B |= 0<<CS10  | 0<<CS11 | 1<<CS12| 1<<WGM12;	//Prescaler set to 256 (8MHz -> 31250 ticks/sec)
	TCNT1 = 0x0000;										//Clear 16-bit timer (set as pre-launch timer)
	TIMSK1 |= 1<<OCIE1A;								//Enable interrupt
	OCR1A = 62499;										//62499 = 2 sec
	
	changeState(preflight);
}

uint16_t getTimer()
{
	return TCNT1;
}

uint16_t getTimerCounter()
{
	return timerCounter16bit;
}

void resettimercounter()
{
	timerCounter16bit = 0;
}

uint8_t getStage()
{
	return state;
}

void changeState(STATES newState)
{
	state = newState;
	stateChanged = 1;
};

ISR(TIMER1_COMPA_vect)
{
	timerCounter16bit++;
}

/*
	This interrupt will trigger every 100ms (10Hz).
	It checks if it is time for a stage change and
	also triggers the main loop which sends and stores
	data.
*/
ISR(TIMER2_COMPA_vect)
{
	if (timerCounter8bit == 2)
	{
		timerCounter8bit = 0;
		//reset_wdt();
		switch(state)
		{
			case preflight:
				runSendOK = 1;
				if (bit_is_clear(PIND, 4))								//Check for 'LO' and count to 1 sec to avoid unwanted voltage peaks, Should be done by interrupt
				{
					LOcounter++;
				}
				else
				{
					LOcounter = 0;
				}
				if (preFlightBatteryVoltageCounter >= 3)
				{
					preFlightBatteryVoltageCounter = 0;
					runBatteryCheck = 1;
				}
				else
				{
					preFlightBatteryVoltageCounter++;
				}
				if (LOcounter >= 10)									
				{
					TCNT1 = 0x0000;										//Reset 16-bit timer (set as post-launch timer)
					resettimercounter();
					changeState(ascent);								//Change the state to Ascent and signal state change through UART
				}
				break;
			case ascent:
				runMainLoop = 1;
				if (TCNT1 > 0 && timerCounter16bit == 5)			//Time condition to start melting
				{
					changeState(heating);
				}
				break;
			case heating:
				runMainLoop = 1;
				if (getArmedStatus() == 1)							
				{
					PORTB |= (1<<PINB6);
					PORTB |= (1<<PINB7);
				}			
				if (TCNT1 > 0 && timerCounter16bit == 12)			//Time condition to start cooling								
				{
					changeState(cooling);
				}
				break;
			case cooling:
				runMainLoop = 1;
				PORTB &= ~(1<<PINB6);
				PORTB &= ~(1<<PINB7);
				if (TCNT1 > 0 && timerCounter16bit >= 16)				//Time condition to shut down
				{
					changeState(shutdown);
				}
				break;
			case shutdown:
				PORTB = 0x00;
				PORTD = 0x00;
				runSendOK = 1;
				break;
			default:
				//UART SEND ERROR
				break;
		}
	}
	else
	{
		timerCounter8bit++;
	}	
}